﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

namespace CloudShot.ImageStorages
{
	public class NivalImageStorage : IImageStorage
	{
		private const string UPLOAD_URL = "http://gyazo.nivalnetwork.com/upload.cgi";

		public Image Logo { get { return null; } }
		public string Name { get { return "Nival Gyazo"; } }

		public string Description
		{
			get { return "Image will be saved in Gyazo Nival server"; }
		}

		public LoginType LoginType { get { return LoginType.None; } }
		public string OAuthTokens { get; set; }

		public ImageFormat[] SupportedFormats
		{
			get { return new[] { ImageFormat.Png }; }
		}

		public SaveType SupportedSaveType
		{
			get { return SaveType.Remote; }
		}

		private ImageFormat _currentImageFormat;
		public ImageFormat CurrentImageFormat
		{
			get { return _currentImageFormat ?? ImageFormat.Png; }
			set
			{
				if (!SupportedFormats.Contains(value))
					_currentImageFormat = ImageFormat.Png;
				else
					_currentImageFormat = value;
			}
		}
		public string FolderToSave { get; set; }

		public ShotInfo SaveImageAsync(Image image, string name, Action<ShotInfo> uploadCompleted)
		{
			ShotInfo result = SaveImage(image, name);
			//в память копируем url на картинку, которую нельзя отредактировать
			//urlResolved(result.Url.AbsoluteUri.Replace(@"/edit/", @"/db/"));
			//saveCompleted(result);
			if (uploadCompleted != null)
				uploadCompleted(result);

			return result;
		}

		public bool IsShotInStorege(ShotInfo shotInfo)
		{
			return true;
		}

		public void SignInAsync(Action<bool> callback)
		{
		}

		public void SignOut()
		{
		}

		private ShotInfo SaveImage(Image image, string filename)
		{
			HttpWebRequest request = WebRequest.Create(UPLOAD_URL) as HttpWebRequest;
			request.ContentType = "multipart/form-data; boundary=----BOUNDARYBOUNDARY----";
			request.UserAgent = "Gyazo";
			request.Credentials = CredentialCache.DefaultCredentials;
			request.Method = "POST";
			request.ServicePoint.Expect100Continue = false;
			request.KeepAlive = false;
			request.Headers.Add("Cache-Control", "no-cache");

			using (MemoryStream ms = new MemoryStream())
			{
				string part1 = "------BOUNDARYBOUNDARY----\r\ncontent-disposition: form-data; name=\"id\"\r\n\r\n20111005210643";
				byte[] p1 = Encoding.ASCII.GetBytes(part1);
				ms.Write(p1, 0, p1.Length);

				string part2 = "\r\n------BOUNDARYBOUNDARY----\r\ncontent-disposition: form-data; name=\"imagedata\"\r\n\r\n";
				byte[] p2 = Encoding.ASCII.GetBytes(part2);
				ms.Write(p2, 0, p2.Length);

				byte[] imageData = ImageToByteArray(image, CurrentImageFormat);
				ms.Write(imageData, 0, imageData.Length);

				string part3 = "\r\n------BOUNDARYBOUNDARY------\r\n";
				byte[] p3 = Encoding.ASCII.GetBytes(part3);
				ms.Write(p3, 0, p3.Length);

				request.ContentLength = ms.Length;

				using (Stream requestStream = request.GetRequestStream())
				{
					ms.Flush();
					ms.Position = 0;
					ms.WriteTo(requestStream);
					requestStream.Close();
				}
			}

			string uploadedFileName = string.Empty;

			WebResponse response = request.GetResponse() as HttpWebResponse;

			using (Stream stream = response.GetResponseStream())
			{
				byte[] respData = new byte[response.ContentLength];

				stream.Read(respData, 0, respData.Length);

				uploadedFileName = Encoding.ASCII.GetString(respData);
			}

			//enable editing in Pixlr
			uploadedFileName = uploadedFileName.Replace(@"/db/", @"/edit/");

			Uri url = new Uri(uploadedFileName);
			string shotName = url.Segments.LastOrDefault() ?? uploadedFileName;

			return new ShotInfo(shotName, url, uploadedFileName, image);
		}

		private static byte[] ImageToByteArray(Image image, ImageFormat imageFormat)
		{
			byte[] imageData;
			using (MemoryStream ms = new MemoryStream())
			{
				image.Save(ms, imageFormat);
				imageData = ms.ToArray();
			}
			return imageData;
		}
	}
}
